﻿
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;

namespace KinonekoSoftware.Foundation.UI.Controls.TextBox
{

    public class NumericTextBox : ForestTextBoxBase
    {
        private                ForestRepeatButtonBase _Up;
        private                ForestRepeatButtonBase _Down;
        private                int                    _Number;
        public static readonly StyledProperty<int>    ValueProperty;
        public static readonly StyledProperty<int>    MinimumProperty;
        public static readonly StyledProperty<int>    MaximumProperty;

        static NumericTextBox()
        {
            ValueProperty   = AvaloniaProperty.Register<NumericTextBox, int>(nameof(Value));
            MinimumProperty = AvaloniaProperty.Register<NumericTextBox, int>(nameof(Value), 0);
            MaximumProperty = AvaloniaProperty.Register<NumericTextBox, int>(nameof(Value), 100);
            ValueProperty.Changed
                         .Subscribe(e =>
                         {
                             var t = (NumericTextBox)e.Sender;
                             t.Text = t.Value.ToString();
                         });
        }
        
        
        public NumericTextBox()
        {
            Text = "0";
        }
        

        protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
        {
            if (e.NameScope.Find<ForestRepeatButtonBase>("PART_UpButton") is {} up)
            {
                _Up       =  up;
                _Up.Click  += OnUp;
            }
            
            if (e.NameScope.Find<ForestRepeatButtonBase>("PART_DownButton") is {} down)
            {
                _Down       =  down;
                _Down.Click += OnDown;
            }
            
            base.OnApplyTemplate(e);
        }
        

        protected override void OnTextChanged()
        {
            _Number = Math.Clamp(int.TryParse(Text, out var n) ? n : 0, Minimum, Maximum);
            Value   = _Number;
            Text    = _Number.ToString();
        }

        private void OnUp(object sender, RoutedEventArgs e)
        {
            _Number = Math.Min(_Number + 1, Maximum);
            Text    = _Number.ToString();
            Value   = _Number;
        }
        
        
        private void OnDown(object sender, RoutedEventArgs e)
        {
            _Number = Math.Max(_Number - 1, Minimum);
            Text    = _Number.ToString();
            Value   = _Number;
        }

        public int Value
        {
            get => GetValue(ValueProperty);
            set => SetValue(ValueProperty, value);
        }
        
        public int Minimum
        {
            get => GetValue(MinimumProperty);
            set => SetValue(MinimumProperty, value);
        }
        
        
        public int Maximum
        {
            get => GetValue(MaximumProperty);
            set => SetValue(MaximumProperty, value);
        }
    }
}